home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / serus221.zip / SERFACE.C < prev    next >
Text File  |  1990-09-01  |  9KB  |  245 lines

  1.    /********************************************************************/
  2.    /*                                                                  */
  3.    /*  Interface routines for  SERIOUS version 2.21                    */
  4.    /*  by Norman J. Goldstein                                          */
  5.    /*                                                                  */
  6.    /********************************************************************/
  7.  
  8.    /*********************************************************************
  9.    This file contains  Turbo C  functions to interface with the SERIOUS
  10.    device driver, version  2.21 ; it should be compiled separately, using
  11.    the command line version of Turbo C, as it contains inline code.
  12.    Link it with the application. The file  serdemo.c  contains a model
  13.    program illustrating the use of  SERIOUS  with the routines in
  14.    this file.
  15.  
  16.    This file also illustrates how to write an assembler interface
  17.    for  SERIOUS , and how to get hold of the entry address of  SERIOUS .
  18.    **********************************************************************/
  19.  
  20. #pragma inline         /* Tell TC about inline code. */
  21. #include <stdio.h>
  22. #include <dos.h>       /* _doserrno */
  23. #include "serface.h"   /* Prototypes for the routines in this source file. */
  24.  
  25. #include <io.h>        /* For open , ioctl . */
  26. #include <fcntl.h>     /* For open flags. */
  27.  
  28. typedef void ( far * PROC)(void);
  29. static PROC EntryAddr;  /* To hold the entry address of  SERIOUS */
  30.  
  31.  
  32. /*- - - - - - - - - SetEntryAddress - - - - - - - - - - - - - - - - -
  33.  * The purpose of this routine is to get the entry address of  SERIOUS
  34.  * and store it in the variable  EntryAddr .
  35.  * It is called only when  SERIOUS  is opened by the application.
  36.  *
  37.  * The return values for  SetEntryAddress
  38.  * are  0        -- success,
  39.  *      non-zero -- low-order byte  = E_NoEntryAddress, and
  40.  *                  high-order byte = _doserrno
  41.  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  42.  */
  43. static unsigned SetEntryAddr(char * devname)
  44. {
  45.  int ret,           /* For return values. */
  46.      SeriousHandle; /* A DOS file handle for the driver. */
  47.  
  48.  if( (SeriousHandle = open(devname,O_RDONLY)) < 0 )
  49.  return _doserrno<<8 | E_NoEntryAddress;
  50.  
  51.  /* This performs an ioctl read from the driver.
  52.     The driver fills in  EntryAddr  with the appropriate address.
  53.     The code, 4 , tells the driver which information is being requested.
  54.   */
  55.  ret = ioctl(SeriousHandle , 2 , &EntryAddr , 4);
  56.  close( SeriousHandle );
  57.  
  58.  /* In case of error, return the error code. */
  59.  if( ret == -1 ) return  _doserrno<<8 | E_NoEntryAddress;
  60.  
  61.   return 0;
  62. }/*SetEntryAddr*/
  63. /*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  64.  
  65.  
  66. /**********************************************************************
  67.    The remaining functions are direct calls into the SERIOUS device
  68.    driver.  Detailed descriptions are in the documentation, which includes,
  69.    as well, how to interpret the error codes.
  70.  
  71.    The one execption is the first function  S_Open , which begins with
  72.    a call to  SetEntryAddr .  Also, for  S_Open , the return error code is
  73.    adjusted in the case where the port is specified as  0 , and the driver
  74.    is reported as  Active .  In this case, the return value is changed
  75.    to  0 .  When the port is specified as  0 , the driver is expected to
  76.    be open.
  77.  
  78.    The "entry" conditions are required by the device driver; setting
  79.    them up is the responsibility of each function.
  80. *** ***********************************************************************/
  81.  
  82. /*- - - - - - - - - -  Function 0: S_Open - - - - - - - - - - - - - - - - -
  83.  *
  84.  * Purpose: Set the static variable  EntryAddr  to the entry address
  85.  *          of  SERIOUS .  Inform the driver of the user's input buffer,
  86.  *          and set up the hardware interrupt routines.
  87.  *
  88.  * Input: inbptr = the far address of the input buffer.
  89.  *        inbord = the order of the input buffer.
  90.  *        port = base port number of the serial chip, and
  91.  *        irq = interrupt request number of the chip.
  92.  *
  93.  * On entry,  es:di -> 1st byte of input buffer,
  94.  *            cl = order of the buffer,
  95.  *            ax = port number, and
  96.  *            ch = interrupt request number.
  97.  *
  98.  * NOTES:
  99.  * -- If  port  is specified as 0, the driver is assumed to be active; this
  100.  *    function will, then, only obtain the entry address of the driver.
  101.  * -- If  inbord  is specified as 0, the driver uses its own buffer, which
  102.  *    was created at installation via a parameter on the command line
  103.  *    in config.sys .  The user need not supply a buffer in this case.
  104.  *
  105.  * Returns an error code:
  106.  *              0 : Success.
  107.  *        non-zero: If the low order byte equals  E_NoEntryAddress, then
  108.  *                  the return value is the return value of  SetEntryAddr .
  109.  *                  Otherwise, the return value is the error code of  SERIOUS .
  110.  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  111.  */
  112. unsigned S_Open(char * devname , unsigned port , unsigned irq ,
  113.                 char far * inbptr , unsigned inbord)
  114. {
  115.  unsigned u;
  116.  
  117.  /* Sets the static variable  EntryAddr  to the entry address of  SERIOUS . */
  118.  if( (u = SetEntryAddr(devname)) != 0 ) return u;
  119.  
  120.  /* Now set up the registers for the  open  call into  SERIOUS . */
  121.  asm mov bx , 0
  122.  asm les di , inbptr
  123.  asm mov cl,  byte ptr inbord
  124.  asm mov ch,  byte ptr irq
  125.  asm mov ax , port
  126.  asm call dword ptr EntryAddr
  127.  
  128.  asm mov u , bx    /* Save the error code in  u . */
  129.  
  130.  /* Return an appropriate error code if the driver is assumed "open" . */
  131.  if( (port == 0) && (u == ERR_Active) ) return 0;
  132.  
  133.  return u;
  134. }/* S_Open */
  135.  
  136.  
  137. /*- - - - - - - - Function 1: S_SetParms - - - - - - - - - - - - - - -
  138.  *
  139.  * Purpose: Set the transmission parameters.
  140.  *
  141.  * Input: baud = rate of transmission, in bits/second.
  142.  *        data = the number of data bits in each character.
  143.  *        stop = the number of stop bits for each character.
  144.  *        parity is the code to specify the type of parity generated.
  145.  *
  146.  * On entry, ax = baud
  147.  *           ch = stop , cl = data
  148.  *           dx = parity
  149.  *
  150.  * Returns an error code.
  151.  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  152.  */
  153. unsigned S_SetParms( unsigned baud, unsigned data, unsigned stop,
  154.                      unsigned parity )
  155. {
  156.  asm mov bx , 1
  157.  asm mov ax , baud
  158.  asm mov cl , byte ptr data
  159.  asm mov ch , byte ptr stop
  160.  asm mov dx , parity
  161.  asm call dword ptr EntryAddr
  162.  return _BX;
  163. }/* S_SetParms */
  164.  
  165.  
  166. /*- - - - - - - - - - - -  Function 2: S_Close - - - - - - - - - - - -
  167.  *
  168.  * Purpose: Disable the UART, and restore the hardware interrupt vectors
  169.  *          to their values before the previous call to  S_Open .  It is
  170.  *          important to close  SERIOUS  before deallocating the input buffer.
  171.  *
  172.  * Returns an error.
  173.  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  174.  */
  175. unsigned S_Close(void)
  176. {
  177.  asm mov bx , 2
  178.  asm call dword ptr EntryAddr
  179.  return _BX;
  180. }/* S_Close */
  181.  
  182.  
  183. /*- - - - - - - - - - - Function 3: S_SendChar - - - - - - - - - - - - - -
  184.  *
  185.  * Purpose: To send a character to the remote machine.
  186.  *
  187.  * Input: c = the character to be sent.
  188.  *
  189.  * On entry, al = c .
  190.  *
  191.  * Returns an error.
  192.  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  193.  */
  194. unsigned S_SendChar( char c )
  195. {
  196.  asm mov bx , 3
  197.  asm mov al , c
  198.  asm call dword ptr EntryAddr
  199.  return _BX;
  200. }/* S_Close */
  201.  
  202.  
  203. /*- - - - - - - - - - -  Function 4: S_RecvChar - - - - - - - - - - - - - -
  204.  *
  205.  * Purpose: To receive a character from the remote machine.
  206.  *
  207.  * Returns the character received, if there is one.
  208.  *         If there is none, the return value is  -1 .
  209.  *- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  210.  */
  211. int S_RecvChar(void)
  212. {
  213.  asm mov bx , 4
  214.  asm call dword ptr EntryAddr
  215.  /*
  216.     Note: The return value is already in the  AX  register, having been placed
  217.           there by  SERIOUS .  The error code (in BX)